using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
using static Enums;

public class GameMonoBehaviour : UIFormLogic
{
    [SerializeField]
    private string m_GameMonoBehaviourName;

    public string GameMonoBehaviourName { get => m_GameMonoBehaviourName; set => m_GameMonoBehaviourName = value; }

    protected GameMonoBehaviour UIFormLogic
    {
        get;
        private set;
    }

    private bool m_IsInited = false;

    /// <summary>
    /// 资源模块
    /// </summary>
    public IResModule Res { get; private set; }

    private bool m_ResShare = false;

#if UNITY_EDITOR

    protected virtual void OnValidate()
    {
        if (m_GameMonoBehaviourName.IsNullOrEmpty())
        {
            m_GameMonoBehaviourName = GetType().Name;
        }
    }

#endif

    private void Awake()
    {
        InitBehaviour();
    }

    public void InitBehaviour()
    {
        if (m_IsInited)
            return;
        m_IsInited = true;
        var form = GetComponentInParent<UGUIForm>();
        IResModule formRes = null;
        bool isShare = form != null && TryGetResFromForm(form, out formRes);
        InitRes(formRes ?? new ResModule(), isShare);
        OnAwake();
    }

    /// <summary>
    /// 尝试从 UGUIForm 获取 Res 模块（如果 UGUIForm 有 Res 属性）
    /// </summary>
    private bool TryGetResFromForm(UGUIForm form, out IResModule res)
    {
        res = null;
        // 如果 UGUIForm 有 Res 属性，可以通过反射获取
        // 这里先返回 null，如果后续 UGUIForm 添加了 Res 属性，可以在这里实现
        return false;
    }

    /// <summary>
    /// 初始化资源模块
    /// </summary>
    /// <param name="res">资源模块</param>
    /// <param name="isShare">是否共享资源模块</param>
    public void InitRes(IResModule res, bool isShare = false)
    {
        Res = res;
        m_ResShare = isShare;
    }

    protected virtual void OnAwake()
    {

    }

    protected virtual void Start()
    {
    }

    protected virtual void OnEnable()
    {
        Register();
    }

    protected virtual void OnDisable()
    {
        UnRegister();
    }

    protected virtual void OnDestroy()
    {
        Unloads();
    }

    /// <summary>
    /// 注册事件
    /// </summary>
    protected virtual void Register()
    {
    }

    /// <summary>
    /// 解绑事件
    /// </summary>
    protected virtual void UnRegister()
    {
    }

    /// <summary>
    /// 卸载资源
    /// </summary>
    public virtual void Unloads()
    {
        if (!m_ResShare && Res != null)
        {
            Res.Dispose();
        }
    }

    /// <summary>
    /// 延迟几秒调用
    /// </summary>
    /// <param name="time">延迟时间（秒）</param>
    /// <param name="action">要执行的动作</param>
    public Coroutine Invoke(float time, Action action) => StartCoroutine(Utility.Coroutine.Delay(time, action));

#if UNITY_EDITOR
    #region 避免错误调用

    protected internal sealed override void OnInit(object userData)
    {
        base.OnInit(userData);
    }

    protected internal sealed override void OnClose(bool isShutdown, object userData)
    {
        base.OnClose(isShutdown, userData);
    }

    protected internal sealed override void OnCover()
    {
        base.OnCover();
    }

    protected internal sealed override void OnDepthChanged(int uiGroupDepth, int depthInUIGroup)
    {
        base.OnDepthChanged(uiGroupDepth, depthInUIGroup);
    }

    protected internal sealed override void OnOpen(object userData)
    {
        base.OnOpen(userData);
    }

    protected internal sealed override void OnPause()
    {
        base.OnPause();
    }

    protected internal sealed override void OnRecycle()
    {
        base.OnRecycle();
    }

    public override void OnReFirst()
    {
        base.OnReFirst();
    }

    protected internal sealed override void OnRefocus(object userData)
    {
        base.OnRefocus(userData);
    }

    protected internal sealed override void OnResume()
    {
        base.OnResume();
    }

    protected internal sealed override void OnReveal()
    {
        base.OnReveal();
    }

    protected internal sealed override void OnUpdate(float elapseSeconds, float realElapseSeconds)
    {
        base.OnUpdate(elapseSeconds, realElapseSeconds);
    }

    #endregion
#endif

}
